<?php


namespace App\Services\Tools;


use App\Exceptions\BasicException;
use App\Repositories\LogRepository;

class MhuaPay
{
    //微信H5
    public const PRODUCT_H5_WEIXIN = 'H5_WEIXIN';
    //微信公众号支付
    public const PRODUCT_JSAPI_WEIXIN = 'JSAPI_WEIXIN';
    //微信APP支付
    public const PRODUCT_APP_WEIXIN = 'APP_WEIXIN';
    public const PAY_WEIXIN = 'WEIXIN';
    public const PAY_ALIPAY = 'ALIPAY';

    public function wechatApp($orderSn, $money, $data, $userIp, $business_id = 0)
    {
        $data_pay = $this->getParams($orderSn, $money, $data, $userIp, $business_id);
        if ($data['payType'] == self::PRODUCT_H5_WEIXIN) {
            return $data_pay;
        }
        return $data_pay['data']['payInfo'];
    }
    // 参数 签名

    /**
     * @param $productCode
     * @param $orderSn
     * @param $money
     * @param $data
     * @param $userIp
     * @return array
     * @throws BasicException
     */
    private function getParams($orderSn, $money, $data, $userIp, $business_id): array
    {
        $originParams = [
            "merAccount" => $data['key'], // 商户标识，由系统生成
            "merNo" => $data['mch_id'],  // 用户编号，由系统生成
//            "appId" => $data['appid'],
            "orderId" => $orderSn, // 商户订单号，由商户自行生成，必须唯一
            "time" => time(),  // 商户密钥
            "amount" => intval($money * 100), // 订单金额（单位:元，1分=0.01元）
//            "amount" => intval(0.01 * 100) , // 订单金额（单位:元，1分=0.01元）
            "product" => "派对",  // 商品名称
            'productDesc' => '用户充值',//商品描述
            "payWay" => self::PAY_WEIXIN, // 支付方式，银联：UNIONPAY，微信：WEIXIN，QQ钱包：QQPAY，支付宝：ALIPAY，收银台：CASHIER
            "payType" => $data['payType'], //支付类型，
            "userIp" => $userIp, // 用户ip地址
            "returnUrl" => "lureapp://lure-home.kangpingym.top//app",
            "attach" => (string)$business_id,
//            "notifyUrl" => "https://app-api.chaofanwl.cn/api/thirdPay/wxPayMHNotify", // 回调地址
            "notifyUrl" => $data['notify_url'], // 回调地址
        ];
        $logRtx = new LogRepository("mihua-pay");
        $logRtx->log("code", $originParams);
        $logRtx->File();
        //不包括字节类型参数，如文件、字节流，剔除sign字段 剔除值为空的参数
        $sign = self::getSign($originParams, $data['MH_PrivateKey']);
        $originParams['sign'] = $sign;
        $encode_data = self::encryptData($originParams, $data['MH_PrivateKey']);
        //        // 进行请求
        $post_data = array(
            'merAccount' => $data['key'],//商户标识
            'data' => $encode_data
        );
        $pay_data = self::get_curl_request(env("MH_PAY_URL"), $post_data, $data);
        if ($pay_data['code'] !== "000000") {
            $logRtx = new LogRepository("mihua-pay");
            $logRtx->log("code", ":err");
            $logRtx->File();
            throw new BasicException(-1, '支付失败');
        }

        return $pay_data['data'];
    }

    /**
     * @param $url
     * @param $post_data
     * @return array|bool|string
     * @throws BasicException
     */
    public static function get_curl_request($url, $post_data, $data)
    {
        $logRtx = new LogRepository("mihua-pay");
//        $logRtx->log("data",  $post_data);
//        $logRtx->File();
        $ch = curl_init($url);
        $timeout = 6000;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
        $ret = curl_exec($ch);
        curl_close($ch);
        $retjson = json_decode($ret, true);

        if (!self::checkSign($retjson["data"], $data['MH_PublicKey'])) {
//            $logRtx->log("验签成功",  $retjson);
//            $logRtx->File();
//        } else {
            $logRtx->log("验签失败", $retjson);
            $logRtx->File();
            throw new BasicException(-1, '支付失败');
        }
        return $retjson;
    }

    public static function getSign($params, $signKey)//签名方式
    {
//        $logRtx = new LogRepository("mihua-pay");
//        $logRtx->log("params",  $params);
//        $logRtx->File();

        ksort($params);
        $data = "";
        foreach ($params as $key => $value) {
            $data .= trim($value);
        }
        return strtoupper(md5($data . $signKey));
    }

    public static function checkSign($params, $signKey) //验签
    {
        ksort($params);
        $psign = "";
        $data = "";
        foreach ($params as $key => $value) {
            if ($key == "sign") {
                $psign = $value;
            } else {
                $data .= trim($value);
            }
        }
        $sign = strtoupper(md5($data . $signKey));
        if ($psign == $sign) {
            return true;
        } else {
            return false;
        }
    }

    public static function encryptData($params, $privateKey)
    {
        ksort($params);
        $privateWorker = new MhuaKeyWorker($privateKey, MhuaKeyWorker::ASN);
        return $privateWorker->encrypt(json_encode($params));
    }

    public static function decryptData($params, $publicKey)
    {
        $publicWorker = new MhuaKeyWorker($publicKey, MhuaKeyWorker::ASN);
        return $publicWorker->decrypt($params);
    }
}
